package com.jse.api;

import java.io.IOException;
import java.net.http.HttpClient.Version;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jse.Http;
import com.jse.Jse;
import com.jse.json.Json;
import com.jse.json.JsonObject;

/**
 * 微信小程序工具类，提供了获取小程序二维码的功能。
 * 
 * @author dzh
 */
public class WxApp {

    /**
     * 获取指定类型的微信小程序二维码API URL。
     * 
     * @param type 二维码类型，如 "createqrcode" 或 "get".
     * @return 格式化的API URL。
     */
    private static String qrtype(String type) {
        if ("createqrcode".equalsIgnoreCase(type)) {
            return "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
        } else if ("get".equalsIgnoreCase(type)) {
            return "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
        } else {
            return "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
        }
    }

    /**
     * 获取微信小程序的access_token。
     * 
     * @param tbl 请求参数，包含 appid 和 secret。
     * @return access_token 字符串。
     */
    private static String token(Map<String, Object> tbl) {
        String access_token = Jse.cache.get("wxapp.access_token", "");
        if (access_token.isEmpty()) {
            access_token = Http.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
                    .formatted(tbl.remove("appid"), tbl.remove("secret")));
            Jse.cache.put("wxapp.access_token", access_token, 7000000L);
        }
        return Json.parse(access_token, Map.class).get("access_token").toString();
    }

    /**
     * 创建微信小程序的无限期二维码。
     * 
     * @param tbl 请求参数，包含以下字段：
     *             <ul>
     *                 <li>appid (String): 小程序的 appid。</li>
     *                 <li>secret (String): 小程序的 appsecret。</li>
     *                 <li>scene (String): 场景值，最大32个可见字符，只支持数字、大小写英文以及部分特殊字符。</li>
     *                 <li>page (String, optional): 必须是已经发布的小程序存在的页面，如果不填写这个字段，默认跳转至首页。</li>
     *                 <li>file (String): 保存二维码图片的文件路径。</li>
     *                 <li>method (String): 二维码请求的方法类型，如 "getUnlimited"。</li>
     *             </ul>
     */
    public static void qrcode(Map<String, Object> tbl) {
        String token = token(tbl);
        String qrtype = tbl.remove("method").toString();
        String url = qrtype(qrtype).formatted(token);
        String file = tbl.remove("file").toString();
        tbl.remove("appid");
        tbl.remove("secret");
        var headers = new HashMap<String, String>(Map.of("Content-Type", "application/json"));
        Http.send(Version.HTTP_1_1, "POST", url, Json.toJson(tbl), 30000, headers, true, Paths.get(file));
    }

    /**
     * 批量创建微信小程序的无限期二维码。
     * 
     * @param list 请求参数列表，每个元素是一个包含创建二维码所需参数的 Map。
     */
    public static void qrcode(List<Map<String, Object>> list) {
        for (Map<String, Object> tbl : list) {
            qrcode(tbl);
        }
    }

    /**
     * 主方法示例，用于测试生成小程序二维码。
     * 
     * @param args 命令行参数（未使用）。
     * @throws InterruptedException 如果线程被中断，则抛出此异常。
     */
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1; i++) {
            JsonObject tbl = new JsonObject();
            // 公共参数
            tbl.put("appid", "wx7fe1762f4cbb38ee");
            tbl.put("secret", "8f9a49d54e93a58fa1b3c1161eb76b1e");
            // 微信API对应方法参数
            tbl.put("scene", "1,info,info,1");
            tbl.put("page", "pages/tabbar/index");
            // 本插件对应方法
            tbl.put("method", "getUnlimited");
            tbl.put("file", "d:/qr_" + i + ".jpg");
            qrcode(tbl);
        }
    }
}